package com.xz.xzutils.components.console;

import com.intellij.execution.filters.Filter;
import com.intellij.execution.filters.HyperlinkInfo;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 实现跳转到指定类或方法功能
 * </p>
 *
 * @author DONG.WANG17@HAND-CHINA.COM
 * @since 2025/3/19-03-19 21:08
 */
public class SqlConsoleFilter implements Filter {
    private final Project project;
    // 捕获全限定类名和方法名
    private static final Pattern METHOD_PATTERN = Pattern.compile("=== (\\S+?)\\.(\\w+)$");

    SqlConsoleFilter(Project project) {
        this.project = project;
    }

    @Override
    public @Nullable Result applyFilter(@NotNull String line, int i) {
        Matcher matcher = METHOD_PATTERN.matcher(line);
        if (matcher.find()) {
            String className = matcher.group(1);
            String methodName = matcher.group(2);

            // 计算匹配范围
            int start = matcher.end(2) - methodName.length();
            int end = matcher.end(2);


            PsiClass psiClass = findClass(className);
            if (psiClass == null) {
                return null;
            }

            /*
              TODO 方法名称 - 有些查询的 Count mapper 没有对应方法，queryAll --- queryAll_COUNT
              通过下划线分割查询，让其指向同一个方法。规则应该弄为可配置
             */
            PsiMethod[] methods = psiClass.findMethodsByName(methodName.split("_")[0], true);
            if (methods.length == 0) {
                // 匹配失败，计算匹配范围缩小到类
                String[] packageSplit;
                if (className.contains("$")) {
                    packageSplit = className.split("\\$");
                } else {
                    packageSplit = className.split("\\.");
                }
                start = start - packageSplit[packageSplit.length - 1].length() - 1;
                end = end - methodName.length() - 1;
            }
            // 创建跳转链接
            HyperlinkInfo linkInfo = (project) -> {
                if (methods.length > 0) {
                    methods[0].navigate(true);
                } else {
                    psiClass.navigate(true);
                }
            };
            return new Result(i - line.length() + start, i - line.length() + end, linkInfo);
        }
        return null;
    }

    private PsiClass findClass(String className) {
        // 处理内部类（如 Outer$Inner）
        String[] parts = className.split("\\$");

        // 获取类（非全限定名称）
        //PsiClass[] classes = PsiShortNamesCache.getInstance(project).getClassesByName(
        //        parts[0],
        //        GlobalSearchScope.allScope(project)
        //);
        PsiClass currentClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));

        for (int i = 1; i < parts.length && currentClass != null; i++) {
            currentClass = currentClass.findInnerClassByName(parts[i], false);
        }
        return currentClass;
    }
}
